import * as THREE from "three"
import lineEnum from "../enum/line.enum"
import { LineMaterial } from "../module/LinesModule"
import LineGeometry from "../three/LineGeometry"

export default class Line extends THREE.Mesh<LineGeometry, LineMaterial> {
  part: string
  computeLineDistances: () => Line
  instanceDistanceBuffer: THREE.InterleavedBuffer
  constructor(e: LineGeometry, t: LineMaterial) {
    super(e, t)
    this.type = "Line"
    this.part = lineEnum.line
    this.computeLineDistances = (() => {
      const e = new THREE.Vector3()
      const t = new THREE.Vector3()
      return () => {
        const i: any = this.geometry
        const s = i.attributes.instanceStart
        const r = i.attributes.instanceEnd
        const o = new Float32Array(2 * s.data.count)
        for (let i = 0, n = 0, a = s.data.count; i < a; i++, n += 2)
          e.fromBufferAttribute(s, i), t.fromBufferAttribute(r, i), (o[n] = 0 === n ? 0 : o[n - 1]), (o[n + 1] = o[n] + e.distanceTo(t))
        this.instanceDistanceBuffer
          ? (this.instanceDistanceBuffer.set(o, 0), (this.instanceDistanceBuffer.needsUpdate = !0))
          : ((this.instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer(o, 2, 1)),
            i.setAttribute("instanceDistanceStart", new THREE.InterleavedBufferAttribute(this.instanceDistanceBuffer, 1, 0, !1)),
            i.setAttribute("instanceDistanceEnd", new THREE.InterleavedBufferAttribute(this.instanceDistanceBuffer, 1, 1, !1)))
        return this
      }
    })()
    this.geometry = e
    this.material = t
  }
}
